﻿using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Media.Animation;
using Automatic.Models;
using Automatic.Views;
using Demo.Public;
using Demo.Public.Base;
using Demo.Public.Extensions;
using LiveCharts;

namespace Automatic.ViewModels
{
    public class MainViewModel : ViewModelBase
    {
        private ObservableCollection<AlarmItemModel> _AlarmList;
        private string _BadCount;
        private List<MonitorItemModel> _DeviceMonitor;
        private List<MonitorItemModel> _Environments;
        private DelegateCommand _LoadCommand;
        private MonitorView _MonitorView;
        private object _PageContent;
        private ObservableCollection<PersonalItemModel> _PersonalList;
        private string _ProductionCount;
        private ObservableCollection<ProductionModel> _ProductionItems = new();
        private ObservableCollection<RaderSeriesModel> _RaderDatas;
        private DelegateCommand _ReturnMonitorCommand;
        private DelegateCommand _ShowWorkShopDetailCommand;
        private string _Total;
        private ObservableCollection<WorkShopItemModel> _WorkShopItems;

        public MainViewModel()
        {
            //Init().Await(() => IsInitFinished = true, ex => throw ex);
        }

        public bool IsInitFinished { get; private set; }
        public bool IsErrorInit { get; private set; }

        /// <summary>
        /// </summary>
        public ObservableCollection<AlarmItemModel> AlarmList
        {
            get => _AlarmList;
            set
            {
                _AlarmList = value;
                RaisePropertyChanged("AlarmList");
            }
        }

        /// <summary>
        /// </summary>
        public string BadCount
        {
            get => _BadCount;
            set
            {
                _BadCount = value;
                RaisePropertyChanged("BadCount");
            }
        }

        /// <summary>
        /// </summary>
        public ChartValues<int> BadProductCount
        {
            get
            {
                ChartValues<int> bad = new();
                IEnumerable<int> v = ProductionItems.Select(z => z.BadProductCount).AsEnumerable();
                bad.AddRange(v);
                return bad;
            }
        }

        /// <summary>
        /// </summary>
        public List<MonitorItemModel> DeviceMonitor
        {
            get => _DeviceMonitor;
            set
            {
                _DeviceMonitor = value;
                RaisePropertyChanged("DeviceMonitor");
            }
        }

        /// <summary>
        /// </summary>
        public List<MonitorItemModel> Environments
        {
            get => _Environments;
            set
            {
                _Environments = value;
                RaisePropertyChanged("Environments");
            }
        }

        /// <summary>
        /// </summary>
        public DelegateCommand LoadCommand => _LoadCommand ?? (_LoadCommand = new DelegateCommand(OnLoad));

        /// <summary>
        /// </summary>
        public object PageContent
        {
            get => _PageContent;
            set
            {
                _PageContent = value;
                RaisePropertyChanged("PageContent");
            }
        }

        /// <summary>
        /// </summary>
        public ObservableCollection<PersonalItemModel> PersonalList
        {
            get => _PersonalList;
            set
            {
                _PersonalList = value;
                RaisePropertyChanged("PersonalList");
            }
        }

        /// <summary>
        ///     表格
        /// </summary>
        public ChartValues<int> ProductCount
        {
            get
            {
                ChartValues<int> count = new();
                IEnumerable<int> v = ProductionItems.Select(z => z.ProductionCount).AsEnumerable();
                count.AddRange(v);
                return count;
            }
        }

        /// <summary>
        /// </summary>
        public string ProductionCount
        {
            get => _ProductionCount;
            set
            {
                _ProductionCount = value;
                RaisePropertyChanged("ProductionCount");
            }
        }

        /// <summary>
        /// </summary>
        public ObservableCollection<ProductionModel> ProductionItems
        {
            get => _ProductionItems;
            set
            {
                _ProductionItems = value;
                RaisePropertyChanged("ProductionItems");
            }
        }

        /// <summary>
        /// </summary>
        public int ProductMaxHundred
        {
            get
            {
                int n = ProductionItems.Max(z => z.ProductionCount);
                int nextHundred = (int)Math.Ceiling(n / 100.0) * 100;
                return nextHundred;
            }
        }

        /// <summary>
        /// </summary>
        public ChartValues<string> ProductTimes
        {
            get
            {
                ChartValues<string> t = new();
                IEnumerable<string> v = ProductionItems.Select(z => z.ProductTime).AsEnumerable();
                t.AddRange(v);
                return t;
            }
        }

        /// <summary>
        /// </summary>
        public ObservableCollection<RaderSeriesModel> RaderDatas
        {
            get => _RaderDatas;
            set
            {
                _RaderDatas = value;
                RaisePropertyChanged("RaderDatas");
            }
        }

        /// <summary>
        /// </summary>
        public DelegateCommand ReturnMonitorCommand =>
            _ReturnMonitorCommand ?? (_ReturnMonitorCommand = new DelegateCommand(OnReturnMonitor));

        /// <summary>
        /// </summary>
        public DelegateCommand ShowWorkShopDetailCommand => _ShowWorkShopDetailCommand ??
                                                            (_ShowWorkShopDetailCommand =
                                                                new DelegateCommand(OnShowWorkShopDetail));

        /// <summary>
        /// </summary>
        public string Total
        {
            get => _Total;
            set
            {
                _Total = value;
                RaisePropertyChanged("Total");
            }
        }

        /// <summary>
        /// </summary>
        public ObservableCollection<WorkShopItemModel> WorkShopItems
        {
            get => _WorkShopItems;
            set
            {
                _WorkShopItems = value;
                RaisePropertyChanged("WorkShopItems");
            }
        }

        public async Task Init()
        {
            try
            {
                Total = 133.ToString("0000");
                ProductionCount = 8343.ToString("00000");
                BadCount = 25.ToString("000");

                List<Task> tasks = new()
                {
                    InitEnvironments(), InitProduction(), InitAlarms(), InitDevices(), InitPersonal(), InitWorkshop(),
                    InitRaderDatas()
                };
                await Task.WhenAll(tasks);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }

        private async Task InitAlarms()
        {
            await Task.Run(() =>
            {
                AlarmList = new ObservableCollection<AlarmItemModel>();
                AlarmList.Add(new AlarmItemModel { Num = "01", Message = "设备温度过高", Time = "2025-04-01", Length = 5 });
                AlarmList.Add(new AlarmItemModel { Num = "02", Message = "车间温度过高", Time = "2025-04-01", Length = 5 });
                AlarmList.Add(new AlarmItemModel { Num = "03", Message = "设备转速过高", Time = "2025-04-01", Length = 5 });
            });
        }

        private async Task InitDevices()
        {
            await Task.Run(() =>
            {
                DeviceMonitor = new List<MonitorItemModel>();
                DeviceMonitor.Add(new MonitorItemModel { Header = "电能(kw.h)" });
                DeviceMonitor.Add(new MonitorItemModel { Header = "电压(V)" });
                DeviceMonitor.Add(new MonitorItemModel { Header = "电流(A)" });
                DeviceMonitor.Add(new MonitorItemModel { Header = "压差(kpa)" });
                DeviceMonitor.Add(new MonitorItemModel { Header = "温度(℃)" });
                DeviceMonitor.Add(new MonitorItemModel { Header = "震动(mm/s)" });
                DeviceMonitor.Add(new MonitorItemModel { Header = "转速(r/min)" });
                DeviceMonitor.Add(new MonitorItemModel { Header = "气压(kpa)" });
            });
        }

        private async Task InitEnvironments()
        {
            await Task.Run(() =>
            {
                Environments = new List<MonitorItemModel>();
                Environments.Add(new MonitorItemModel { Header = "光照(lux)" });
                Environments.Add(new MonitorItemModel { Header = "噪音(dB)" });
                Environments.Add(new MonitorItemModel { Header = "温度(℃)" });
                Environments.Add(new MonitorItemModel { Header = "湿度(%)" });
                Environments.Add(new MonitorItemModel { Header = "PM2.5(m³)" });
                Environments.Add(new MonitorItemModel { Header = "硫化氢(ppm)" });
                Environments.Add(new MonitorItemModel { Header = "氮气(ppm)" });
            });
        }

        private async Task InitPersonal()
        {
            await Task.Run(() =>
            {
                PersonalList = new ObservableCollection<PersonalItemModel>();

                PersonalList.Add(new PersonalItemModel { Name = "Name1", Duties = "Worker", MainHour = 3 });
                PersonalList.Add(new PersonalItemModel { Name = "Name2", Duties = "Worker", MainHour = 4 });
                PersonalList.Add(new PersonalItemModel { Name = "Name3", Duties = "Worker", MainHour = 3 });
                PersonalList.Add(new PersonalItemModel { Name = "Name4", Duties = "Worker", MainHour = 5 });
                PersonalList.Add(new PersonalItemModel { Name = "Name5", Duties = "Worker", MainHour = 3 });
            });
        }

        private async Task InitProduction()
        {
            await Task.Run(() =>
            {
                ProductionItems.Add(new ProductionModel
                    { ProductionCount = 123, BadProductCount = 45, ProductTime = "6:00" });
                ProductionItems.Add(new ProductionModel
                    { ProductionCount = 234, BadProductCount = 34, ProductTime = "8:00" });
                ProductionItems.Add(new ProductionModel
                    { ProductionCount = 343, BadProductCount = 56, ProductTime = "9:00" });
                ProductionItems.Add(new ProductionModel
                    { ProductionCount = 643, BadProductCount = 23, ProductTime = "10:00" });
                ProductionItems.Add(new ProductionModel
                    { ProductionCount = 368, BadProductCount = 12, ProductTime = "11:00" });
                ProductionItems.Add(new ProductionModel
                    { ProductionCount = 435, BadProductCount = 78, ProductTime = "12:00" });
                ProductionItems.Add(new ProductionModel
                    { ProductionCount = 522, BadProductCount = 36, ProductTime = "13:00" });
                ProductionItems.Add(new ProductionModel
                    { ProductionCount = 214, BadProductCount = 64, ProductTime = "14:00" });
                ProductionItems.Add(new ProductionModel
                    { ProductionCount = 714, BadProductCount = 64, ProductTime = "17:00" });
                RaisePropertyChanged("ProductCount");
                RaisePropertyChanged("BadProductCount");
                RaisePropertyChanged("ProductTimes");
            });
        }

        private async Task InitRaderDatas()
        {
            await Task.Run(() =>
            {
                RaderDatas = new ObservableCollection<RaderSeriesModel>();
                Random random = new();

                for (int i = 0; i < 7; i++)
                {
                    RaderDatas.Add(new RaderSeriesModel { Header = "Tag" + i, Value = random.Next(20, 100) });
                }
                RaisePropertyChanged("RaderDatas");
            });
        }

        private async Task InitWorkshop()
        {
            await Task.Run(() =>
            {
                WorkShopItems = new ObservableCollection<WorkShopItemModel>();
                WorkShopItems.Add(new WorkShopItemModel
                    { Name = "贴片车间", TotlalCount = 40, WorkCount = 20, WaitCount = 10, FaultCount = 5, StopCount = 5 });
                WorkShopItems.Add(new WorkShopItemModel
                    { Name = "分装车间", TotlalCount = 40, WorkCount = 20, WaitCount = 10, FaultCount = 5, StopCount = 5 });
                WorkShopItems.Add(new WorkShopItemModel
                {
                    Name = "贴焊接车间", TotlalCount = 40, WorkCount = 20, WaitCount = 10, FaultCount = 5, StopCount = 5
                });
                WorkShopItems.Add(new WorkShopItemModel
                    { Name = "组装车间", TotlalCount = 40, WorkCount = 20, WaitCount = 10, FaultCount = 5, StopCount = 5 });
                WorkShopItems.Add(new WorkShopItemModel
                    { Name = "包装车间", TotlalCount = 40, WorkCount = 20, WaitCount = 10, FaultCount = 5, StopCount = 5 });
            });
        }

        /// <summary>
        /// </summary>
        private async void OnLoad(object obj)
        {
             await Init();
            }

        /// <summary>
        /// </summary>
        private void OnReturnMonitor(object obj)
        {
            PageContent = _MonitorView;
        }

        /// <summary>
        /// </summary>
        private void OnShowWorkShopDetail(object obj)
        {
            _MonitorView = PageContent as MonitorView;
            WorkShopItemModel model = obj as WorkShopItemModel;
            WorkShopView view = new();
            PageContent = view;

            ThicknessAnimation thicknessAnimation = new(
                new Thickness(0, 50, 0, -50), new Thickness(0, 0, 0, 0), new TimeSpan(0, 0, 0, 0, 400));
            DoubleAnimation doubleAnimation = new(0, 1, new TimeSpan(0, 0, 0, 0, 400));

            Storyboard.SetTarget(thicknessAnimation, view);
            Storyboard.SetTarget(doubleAnimation, view);
            Storyboard.SetTargetProperty(thicknessAnimation, new PropertyPath("Margin"));
            Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("Opacity"));

            Storyboard storyboard = new();
            storyboard.Children.Add(thicknessAnimation);
            storyboard.Children.Add(doubleAnimation);
            storyboard.Begin();
        }
    }
}